﻿namespace BM.Tools.WebControls.MForm.Controls.Helper
{
    using System;
    using System.ComponentModel;
    using System.Globalization;
    using System.IO;
    using System.Reflection;
    using System.Web.UI;

    /// <summary>
    /// This class collects data from the control's properties <see cref="AttributePropertyAttribute" /> attributes
    /// and adds these attributes to the control
    /// </summary>
    public static class AttributeAttacher
    {
        /// <summary>
        /// collects all properties with the AttributeProperty specified and adds them to control's attributes
        /// </summary>
        /// <param name="control">
        /// The control.
        /// </param>
        /// <param name="writer">
        /// The writer.
        /// </param>        
        public static void AddAttributesFromProperties(this Control control, HtmlTextWriter writer)
        {
            foreach (PropertyInfo info in control.GetType().GetProperties())
            {
                var attribute =
                        Attribute.GetCustomAttribute(info, typeof(AttributePropertyAttribute)) as
                        AttributePropertyAttribute;
                if (attribute != null)
                {
                    string value = control.GetPropertyValue(info);
                    if (!string.IsNullOrEmpty(value))
                    {
                        writer.AddAttribute(attribute.Name, value);
                    }
                }
            }
        }

        /// <summary>
        /// gets the value of the property
        /// </summary>
        /// <param name="control">
        /// The control.
        /// </param>
        /// <param name="info">
        /// The property info.
        /// </param>
        /// <returns>
        /// the value as a string
        /// </returns>
        public static string GetPropertyValue(this Control control, PropertyInfo info)
        {
            object value = info.GetValue(control, null);
            PropertyDescriptor descriptor = TypeDescriptor.GetProperties(control).Find(info.Name, false);
            if (descriptor.Attributes[typeof(UrlPropertyAttribute)] != null)
            {
                return control.ResolveClientUrl((string)value);
            }

            TypeConverter converter = descriptor.Converter;
            if (converter != null)
            {
                return converter.ConvertToString(null, CultureInfo.InvariantCulture, value);
            }

            return Convert.ToString(value, CultureInfo.InvariantCulture);
        }

        /// <summary>
        /// adds the specified property to the content of the generated control
        /// </summary>
        /// <param name="control">
        /// The control.
        /// </param>
        /// <param name="writer">
        /// The writer.
        /// </param>
        public static void AddContentFromProperties(this Control control, TextWriter writer)
        {
            foreach (PropertyInfo info in control.GetType().GetProperties())
            {
                var contentProperty =
                        Attribute.GetCustomAttribute(info, typeof(ContentPropertyAttribute)) as ContentPropertyAttribute;
                if (contentProperty != null)
                {
                    writer.Write(control.GetPropertyValue(info));
                }
            }
        }     
    }
}